/********************************************************************
	filename: 	Segment2D.cpp
	created:	2010/04/16
	author:		Xiuwei Chen

	purpose:	Implement of class Segment2D

	All rights Reserved
*********************************************************************/

#include "Segment2D.h"

/// <Summary>
/// Zero of Segment2D
/// </Summary>
const Segment2D Segment2D::Zero = Segment2D(0, 0, 0, 0);

/// <Summary>
/// default constructor
/// </Summary>
Segment2D::Segment2D()
{
}

/// <Summary>
/// constructor
/// </Summary>
Segment2D::Segment2D(const Point2D &_p0, const Point2D &_p1)
	: p0(_p0), p1(_p1)
{
}

/// <Summary>
/// constructor
/// </Summary>
Segment2D::Segment2D(double x0, double y0, double x1, double y1)
	: p0(x0, y0), p1(x1, y1)
{
}

/// <Summary>
/// set value
/// </Summary>
void Segment2D::SetValue(double x0, double y0, double x1, double y1)
{
	p0.x = x0;
	p0.y = y0;
	p1.x = x1;
	p1.y = y1;
}

/// <Summary>
/// set value
/// </Summary>
void Segment2D::SetValue(const Point2D &_p0, const Point2D &_p1)
{
	p0 = _p0;
	p1 = _p1;
}

/// <Summary>
/// overload operation: assignment
/// </Summary>
Segment2D & Segment2D::operator = (const Segment2D &seg)
{
	p0 = seg.p0;
	p1 = seg.p1;
	return *this;
}

/// <Summary>
/// overload operation: "=="
/// </Summary>
bool Segment2D::operator == (const Segment2D &seg) const
{
	return (p0 == seg.p0 && p1 == seg.p1)
		|| (p0 == seg.p1 && p1 == seg.p0);
}

/// <Summary>
/// overload operation: "!="
/// </Summary>
bool Segment2D::operator != (const Segment2D &seg) const
{
	return (p0 != seg.p0 || p1 != seg.p1)
		&& (p0 != seg.p1 || p1 != seg.p0);
}

/// <Summary>
/// overload operation: unary "-"
/// </Summary>
Segment2D Segment2D::operator - () const
{
	return Segment2D(p1, p0);
}

/// <Summary>
/// Translation by 2D vector: (p0 + v, p1 + v)
/// </Summary>
void Segment2D::Translation(const Vector2D &v)
{
	p0 += v;
	p1 += v;
}

/// <Summary>
/// Translation by 2D vector: (p0 + v0, p1 + v1)
/// </Summary>
void Segment2D::Translation(const Vector2D &v0, const Vector2D &v1)
{
	p0 += v0;
	p1 += v1;
}

/// <Summary>
/// get the module of vector (equal to the length)
/// </Summary>
double Segment2D::Norm() const
{
	return sqrt((p1.x - p0.x) * (p1.x - p0.x) + (p1.y - p0.y) * (p1.y - p0.y));
}

/// <Summary>
/// get the module square of vector (equal to the length)
/// </Summary>
double Segment2D::Norm2() const
{
	return (p1.x - p0.x) * (p1.x - p0.x) + (p1.y - p0.y) * (p1.y - p0.y);
}

/// <Summary>
/// Segment Normalize
/// </Summary>
void Segment2D::Normalize()
{
	if(p1 < p0)
	{
		std::swap(p0, p1);
	}
}

/// <Summary>
/// get vertical vector (clockwise direction)
/// </Summary>
Vector2D Segment2D::Vertical(bool unit) const
{
	Vector2D ret(p1.y - p0.y, p0.x - p1.x);
	if(unit == true)
	{
		ret.Normalize();
	}
	return ret;
}

/// <Summary>
/// get horizontal vector of 2D line
/// </Summary>
Vector2D Segment2D::Horizontal(bool unit) const
{
	Vector2D ret(p1.x - p0.x, p1.y - p0.y);
	if(unit == true)
	{
		ret.Normalize();
	}
	return ret;
}

/// <Summary>
/// rotate counter clockwise around a point (radian)
/// </Summary>
void Segment2D::Rotation(const Point2D &center, double angle)
{
	p0.Rotation(center, angle);
	p1.Rotation(center, angle);
}

/// <Summary>
/// Center
/// </Summary>
Point2D Segment2D::Center() const
{
	return Point2D(p0.x + (p1.x - p0.x) / 2, p0.y + (p1.y - p0.y) / 2);
}